Содержание

  • 1  Загрузка данных
  • 2  Умножение матриц
  • 3  Алгоритм преобразования
  • 4  Проверка алгоритма
  • 5  Вывод
  • 6  Чек-лист проверки

Защита персональных данных клиентов¶

Вам нужно защитить данные клиентов страховой компании «Хоть потоп». Разработайте такой метод преобразования данных, чтобы по ним было сложно восстановить персональную информацию. Обоснуйте корректность его работы.

Нужно защитить данные, чтобы при преобразовании качество моделей машинного обучения не ухудшилось. Подбирать наилучшую модель не требуется.

Загрузка данных¶

In [1]:
import pandas as pd
import numpy as np
import seaborn as sns
import warnings

from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

warnings.filterwarnings('ignore')
In [2]:
try:
    data = pd.read_csv('/datasets/insurance.csv')
except:
    data = pd.read_csv('F:/insurance.csv')
In [3]:
display(data.head(), data.shape,)
Пол Возраст Зарплата Члены семьи Страховые выплаты
0 1 41.0 49600.0 1 0
1 0 46.0 38000.0 1 1
2 0 29.0 21000.0 0 0
3 0 21.0 41700.0 2 0
4 1 28.0 26100.0 0 0
(5000, 5)
In [4]:
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5000 entries, 0 to 4999
Data columns (total 5 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   Пол                5000 non-null   int64  
 1   Возраст            5000 non-null   float64
 2   Зарплата           5000 non-null   float64
 3   Члены семьи        5000 non-null   int64  
 4   Страховые выплаты  5000 non-null   int64  
dtypes: float64(2), int64(3)
memory usage: 195.4 KB
In [5]:
data.describe()
Out[5]:
Пол Возраст Зарплата Члены семьи Страховые выплаты
count 5000.000000 5000.000000 5000.000000 5000.000000 5000.000000
mean 0.499000 30.952800 39916.360000 1.194200 0.148000
std 0.500049 8.440807 9900.083569 1.091387 0.463183
min 0.000000 18.000000 5300.000000 0.000000 0.000000
25% 0.000000 24.000000 33300.000000 0.000000 0.000000
50% 0.000000 30.000000 40200.000000 1.000000 0.000000
75% 1.000000 37.000000 46600.000000 2.000000 0.000000
max 1.000000 65.000000 79000.000000 6.000000 5.000000
In [6]:
display(data.corr(), sns.heatmap(data.corr(), annot=True))
Пол Возраст Зарплата Члены семьи Страховые выплаты
Пол 1.000000 0.002074 0.014910 -0.008991 0.010140
Возраст 0.002074 1.000000 -0.019093 -0.006692 0.651030
Зарплата 0.014910 -0.019093 1.000000 -0.030296 -0.014963
Члены семьи -0.008991 -0.006692 -0.030296 1.000000 -0.036290
Страховые выплаты 0.010140 0.651030 -0.014963 -0.036290 1.000000
<AxesSubplot:>
In [7]:
data.isna().sum()
Out[7]:
Пол                  0
Возраст              0
Зарплата             0
Члены семьи          0
Страховые выплаты    0
dtype: int64
In [8]:
data.duplicated().sum()
Out[8]:
153

Комментарий:

Данные успешно загружены и имеют подходящий тип данных. Для удобства переведем возраст и зарплату в целочисленный формат, так как дробная часть не имеет значения в данном контексте. В таблице отсутствуют лишние столбцы и пропущенные значения. Дубликаты будут удалены, их происхождение неясно, однако они не являются необходимыми для обучения модели. Проверка основных статистических показателей не выявила явных выбросов. Наблюдается высокая корреляция между возрастом и зарплатой (коэффициент корреляции 0.65).

In [9]:
data = data.drop_duplicates()
data['Возраст'] = data['Возраст'].astype("int64")
data['Зарплата'] = data['Зарплата'].astype("int64")

Умножение матриц¶

В этом задании вы можете записывать формулы в Jupyter Notebook.

Чтобы записать формулу внутри текста, окружите её символами доллара \$; если снаружи — двойными символами \$\$. Эти формулы записываются на языке вёрстки LaTeX.

Для примера мы записали формулы линейной регрессии. Можете их скопировать и отредактировать, чтобы решить задачу.

Работать в LaTeX необязательно.

Обозначения:

  • $X$ — матрица признаков (нулевой столбец состоит из единиц)

  • $y$ — вектор целевого признака

  • $P$ — матрица, на которую умножаются признаки

  • $w$ — вектор весов линейной регрессии (нулевой элемент равен сдвигу)

Предсказания:

$$ a = Xw $$

Задача обучения:

$$ w = \arg\min_w MSE(Xw, y) $$

Формула обучения:

$$ w = (X^T X)^{-1} X^T y $$

Ответ: R2 не изменится

Обоснование:

Умножение матрицы на матрицу возможно, если ширина первой матрицы $А(𝑚×𝑛)$ равна высоте второй матрицы $P (𝑛×r)$. Тогда размер произведения этих матриц будет $m×r$. Размерность n «cхлопывается».

При умножении признаков выборки $A$ размерностью $(3750,4)$ на обратимую произвольную матрицу $P$ размерностью $(4,4)$, результатом получаем новый (изменённый) набор данных скалярных произведений $M$ размернотью $(3750, 4)$
Формула выглядит следующим образом: $$ Mij = (Ai,Bj) $$ В каждую новую ячейку записывается результат сложения произведений строки $i$ на столбец $j$. Так например в первой ячейке новой таблицы будет записан результат по этой формуле: $$ M_{11}=A_{11}×P_{11} + A_{12}×P_{21} + A_{13}×P_{31} + A_{14}×P_{41} $$

Далее вычисляется важный параметр - вектор $w$ по формуле: $$ w = (X^T X)^{-1} X^T y $$


В которой $X$ - таблица признков, где нулевой столбец заполнен $1$ (единицами), а $y$ - вектор целевого признака

$$ X_{i} = (1 M_{i2} M_{i3} M_{i4} M_{i5}) $$

В Линейной регрессии предсказания вычисляются по формуле:

$$ a = Xw + w0 $$

, где $w0$ - значение нулевого аргумента вектора $w$, которое предствляет собой величину сдвига модели, при подборе которого можно достигать более низкого значения среднеквадратичного отклонения $MSE$

Рассмотрим упрощённую запись формулы предсказания Линейной регрессии $ a = X_i w $, где $X_i$ - новые строки признаков
Подставим вместо параметра $w$, формулу её вычисления: $$ a = X_i w = X_i (X^T X)^{-1} X^T y $$

Упроситим формулу используя принцип ассоциативности ($A(BC) = (AB)C$) и то, что транспонированное произведение матриц равно произведению транспонированных матриц взятых в обратном порядке ($(AB)^T = B^T A^T$):

$$ a = X_i (X^T X)^{-1} X^T y = X_iX^{-1}(X^T)^{-1}X^T y = X_iX^{-1}y $$

Домножим наши признаки на случайную матрицу $P$, в которой число строк равно чилу столбцов $X$ и $P$ - обратима, то есть из матрицы $P$ можно получить матрицу $P^{-1}$, при этом $PP^{-1} = E$, где $E$ - единичная матрица

Если обучить нашу модель на новых (изменённых) признаках, то модель найдёт новые коэффициенты $w'$

$$ w' = ((XP)^T(XP))^{-1}(XP)^Ty $$

Подставим их в формулу предсказания и упростим выражение

$$ a'= X_iPw' = X_iP((XP)^T(XP))^{-1}(XP)^Ty = X_iP(XP)^{-1}((XP)^T)^{-1}(XP)^Ty = X_iX^{-1}y $$

Таким образом мы пришли к заключению, о том что результат предсказания не изменится не смотря на измениения признаков, т.к. исходя из результатов наших преобразований очевидно, что $a$ = $a'$

Алгоритм преобразования¶

Алгоритм

Мы создаем квадратную матрицу, размер которой соответствует количеству признаков, и заполняем ее случайными числами. Затем мы проверяем, является ли эта матрица обратимой, то есть имеет обратную матрицу. Если матрица обратима, мы умножаем наши признаки на эту матрицу.

Важно отметить, что требуется, чтобы матрица была обратимой, чтобы мы могли успешно восстановить исходные данные. В противном случае, если матрица необратима, мы не сможем расшифровать наши данные.

Обоснование

Мы можем ожидать, что качество линейной регрессии будет одинаковым до и после преобразования данных. Преобразование данных не влияет на способность модели предсказывать целевой признак. Однако, эти действия имеют важное значение для защиты персональных данных клиентов. В случае возможной утечки данных, преобразование матрицы признаков обеспечивает дополнительную безопасность, поскольку злоумышленникам эти данные будут бесполезны.

Проверка алгоритма¶

In [10]:
features = data.drop(["Страховые выплаты"], axis=1)
target = data["Страховые выплаты"]
features.shape, target.shape
Out[10]:
((4847, 4), (4847,))
In [11]:
matrix = np.random.randint(100,size = (4, 4))
matrix
Out[11]:
array([[61, 78, 66, 57],
       [96, 25, 62, 81],
       [33,  9, 67, 57],
       [22, 51, 88, 30]])
In [12]:
matrix_inv = np.linalg.inv(matrix)
matrix_inv
Out[12]:
array([[-0.01671234,  0.02824602, -0.03262188,  0.01747076],
       [ 0.02102849, -0.01135376, -0.00134096, -0.00675118],
       [-0.0169794 ,  0.00747934, -0.0059387 ,  0.02335016],
       [ 0.02631352, -0.02335177,  0.04362251, -0.03649535]])
In [13]:
model = LinearRegression(normalize=True).fit(features, target)
predictions = model.predict(features)
r2_score_value = r2_score(target, predictions)
print(f"R2_score: {r2_score_value:.13f}")
R2_score: 0.4302010046633
In [14]:
features_matrix = features.dot(matrix)
In [15]:
model = LinearRegression(normalize = True).fit(features_matrix, target)
predictions = model.predict(features_matrix)
r2_score_value = r2_score(target, predictions)
print(f"R2_score: {r2_score_value:.13f}")
R2_score: 0.4302010046633

Вывод¶

Поскольку значения сошлись, мы успешно защитили данные пользователей, применив умножение на матрицу, при этом не потеряв качество модели.
Оставлю немного полезного материала::

Оставлю хороший учебник по ML:

  • https://academy.yandex.ru/handbook/ml
  • https://habr.com/ru/post/595281/

Немного новостей с мира DL(вдруг заинтересует):

  • https://habr.com/ru/company/ods/blog/686962/

Вот тут проходят всякие соревнования, можешь себя попробовать:

  • https://hacks-ai.ru/championships#competitions

Если хочешь подтянуть Математику для DS то, например:

  • https://mml-book.github.io/book/mml-book.pdf
  • https://www.coursera.org/specializations/mathematics-machine-learning

Coursera, к сожалению уходит из России...но все равно расскажу лайфхак как там получить курс бесплатно. https://techrocks.ru/2021/07/31/coursera-edx-udacity-free-learning-resources/#:~:text=%D0%9D%D0%BE%20%D0%B5%D1%81%D1%82%D1%8C%20%D0%B5%D1%89%D0%B5%20%D0%BE%D0%B4%D0%BD%D0%B0%20%D0%BE%D0%BF%D1%86%D0%B8%D1%8F,%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B2%20%D1%82%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B4%D0%B2%D1%83%D1%85%20%D0%BD%D0%B5%D0%B4%D0%B5%D0%BB%D1%8C.

Возможно, что нить пригодится:

  • https://drive.google.com/file/d/1r8CJHH_hwDM16l1Pnpb4KJzoJFrJ5XRi/view
  • https://arxiv.org/ftp/arxiv/papers/2201/2201.00650.pdf
  • https://github.com/slgero/testovoe

Курс от МФТИ математика для DS:

  • https://www.youtube.com/watch?v=xccjt6lOoow&list=PLk4h7dmY2eYHHTyfLyrl7HmP-H3mMAW08&index=1

Тут много соревнований/лекций:

  • https://ods.ai/

stepic NLP/CV:

  • https://stepik.org/course/54098/syllabus
  • https://stepik.org/course/50352/syllabus

Еще есть от ВШЭ:

  • https://www.youtube.com/watch?v=mwjQaNt8qxk&list=PLEwK9wdS5g0og-DcF1apxutSM0GDLHz_3&ab_channel=%D0%A4%D0%9A%D0%9D%D0%92%D0%A8%D0%AD%E2%80%94%D0%B4%D0%B8%D1%81%D1%82%D0%B0%D0%BD%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5%D0%B7%D0%B0%D0%BD%D1%8F%D1%82%D0%B8%D1%8F
  • https://github.com/hse-ds/iad-deep-learning

Чек-лист проверки¶

Поставьте 'x' в выполненных пунктах. Далее нажмите Shift+Enter.

  • Jupyter Notebook открыт
  • Весь код выполняется без ошибок
  • Ячейки с кодом расположены в порядке исполнения
  • Выполнен шаг 1: данные загружены
  • Выполнен шаг 2: получен ответ на вопрос об умножении матриц
    • Указан правильный вариант ответа
    • Вариант обоснован
  • Выполнен шаг 3: предложен алгоритм преобразования
    • Алгоритм описан
    • Алгоритм обоснован
  • Выполнен шаг 4: алгоритм проверен
    • Алгоритм реализован
    • Проведено сравнение качества моделей до и после преобразования